package com.drama.api.sys.dramas.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.drama.api.base.Constants;
import com.drama.api.base.IDEntity;
import com.drama.api.base.Type;
import com.drama.api.company.dramas.dao.DramasExamineDao;
import com.drama.api.company.dramas.dao.VideoLogDao;
import com.drama.api.company.dramas.domain.po.DramasExaminePO;
import com.drama.api.company.dramas.domain.po.VideoLogPO;
import com.drama.api.company.message.dao.CompanyMessageDao;
import com.drama.api.sys.company.dao.SysCompanyDao;
import com.drama.api.sys.company.domain.po.SysCompanyPO;
import com.drama.api.sys.dramas.dao.SysDramasDao;
import com.drama.api.sys.dramas.dao.SysDramasScheduleDao;
import com.drama.api.sys.dramas.dao.SysVideoDao;
import com.drama.api.sys.dramas.domain.po.SysDramasPO;
import com.drama.api.sys.dramas.domain.po.SysDramasSchedulePO;
import com.drama.api.sys.dramas.domain.po.SysVideoPO;
import com.drama.api.sys.dramas.domain.vo.*;
import com.drama.api.sys.dramas.service.ISysDramasService;
import com.drama.api.sys.log.dao.SysLogDao;
import com.drama.api.sys.user.dao.SysUserDao;
import com.drama.api.sys.user.domain.po.SysUserPO;
import com.drama.api.task.CompanyMessageThread;
import com.drama.api.task.SysLogThread;
import com.drama.exception.BusinessException;
import com.drama.util.KeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Transactional
@Slf4j
public class SysDramasServiceImpl implements ISysDramasService {

    @Autowired
    SysDramasDao sysDramasDao;

    @Autowired
    SysDramasScheduleDao sysDramasScheduleDao;

    @Autowired
    SysVideoDao sysVideoDao;

    @Autowired
    SysUserDao sysUserDao;

    @Autowired
    DramasExamineDao dramasExamineDao;

    @Autowired
    private SysLogDao sysLogDao;

    @Autowired
    private CompanyMessageDao companyMessageDao;


    @Autowired
    private SysCompanyDao sysCompanyDao;


    @Override
    public List<SysDramasVO> getList(SysDramasSearchVO searchVO) {
        return sysDramasDao.getList(searchVO);
    }
    @Override
    public List<SysDramasVO> getRecycleList(SysDramasSearchVO searchVO) {
        return sysDramasDao.getRecycleList(searchVO);
    }

    @Override
    public SysDramasVO getOne(String id) {
        return sysDramasDao.getOne(id);
    }



    @Override
    public List<SysDramasCountVO> count(SysDramasCountSearchVO searchVO) {

        List<SysDramasCountVO> list= sysDramasDao.getCount(searchVO);
        HashMap maps=new HashMap<>();
        if(list!=null&&list.size()>0){
            maps=(HashMap<Integer, Integer>) list.stream().collect(Collectors.toMap(SysDramasCountVO::getDramaState,SysDramasCountVO::getNum));
        }
        List<SysDramasCountVO> resultList=new ArrayList<>();
        for (int i = 1; i <9 ; i++) {
            if(i==1||i==3||i==5||i==7||i==8){
                SysDramasCountVO companyDramasCountVO=new SysDramasCountVO();
                companyDramasCountVO.setDramaState(i);
                companyDramasCountVO.setNum(0);
                if(maps.containsKey(i)){
                    companyDramasCountVO.setNum((Integer) maps.get(i));
                }
                resultList.add(companyDramasCountVO);
            }
        }
        return resultList;
    }

    @Override
    public List<SysVideoVO> getVideoList(SysVideoSearchVO searchVO) {
        List<SysVideoVO> list=sysVideoDao.getList(searchVO);
        if(list!=null&&list.size()>0){
            for (SysVideoVO companyVideoVO:list){
                companyVideoVO.setVideoOldUrl(KeyUtil.encryptFromString(companyVideoVO.getVideoOldUrl()));
                if(StringUtils.isNotBlank(companyVideoVO.getVideoUrl())){
                    companyVideoVO.setVideoUrl(KeyUtil.encryptFromString(companyVideoVO.getVideoUrl()));
                }
            }
        }
        return list;
    }

    @Override
    public List<SysDramasScheduleVO> getScheduleList(SysDramasScheduleSearchVO searchVO) {
        return sysDramasScheduleDao.getList(searchVO);
    }


    @Override
    public void updateDramaNo(SysDramasNoVO vo) {
        SysDramasPO sysDramasPO=sysDramasDao.selectByPrimaryKey(vo.getId());
        if(sysDramasPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR);
        }
        sysDramasPO.preUpdate();
        sysDramasPO.setDramaNo(vo.getDramaNo());
        sysDramasDao.updateByPrimaryKeySelective(sysDramasPO);
    }




    @Autowired
    private VideoLogDao videoLogDao;


    @Override
    public void referExamine(SysDramasExamineVO vo) {
        SysDramasPO sysDramasPO=sysDramasDao.selectByPrimaryKey(vo.getId());
        if(sysDramasPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR);
        }
        if(sysDramasPO.getDramaState()!=1){
            throw new BusinessException(Type.FAIL.getCode(),"当前状态不能审核！");
        }
        SysUserPO sysUserPO=sysUserDao.selectByPrimaryKey(StpUtil.getLoginId());
        if(sysUserPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR);
        }
        sysDramasPO.preUpdate();
        sysDramasPO.setDramaNo(vo.getDramaNo());
        SysDramasSchedulePO sysDramasSchedulePO=new SysDramasSchedulePO();
        sysDramasSchedulePO.setDramaId(sysDramasPO.getId());
        sysDramasSchedulePO.setLogState(vo.getExamineState());
        sysDramasSchedulePO.setLogType(2);
        if(vo.getExamineState()==1){
//            if(vo.getDramaNo().length()>16||vo.getDramaNo().length()<15){
//                throw new BusinessException(Type.FAIL.getCode(),"备案号长度应再15-16位！");
//            }
            sysDramasPO.setDramaState(3);
            sysDramasPO.setDramasSchedule(3);
            sysDramasPO.setScheduleDateB(sysDramasPO.getUpdateDate());
            sysDramasSchedulePO.setLogTitle("审核通过，操作人："+sysUserPO.getUserName());
            new CompanyMessageThread(companyMessageDao, sysDramasPO.getCompanyId(),"剧目提审进度通知",
                    "剧目（剧名："+sysDramasPO.getDramaName()+"）审核通过，详情前往【剧目管理】中进行查阅。"
                    ,"/drama",1,(String) StpUtil.getLoginId()).start();
        }
        if(vo.getExamineState()==2){
            //整理日志
            Example videLogExample=new Example(VideoLogPO.class);
            videLogExample.and().andEqualTo("dramaId",sysDramasPO.getId());
            videoLogDao.deleteByExample(videLogExample);
            videoLogDao.insertByDramaId(sysDramasPO.getId());

            Example example=new Example(SysVideoPO.class);
            example.and().andEqualTo("dramaId",sysDramasPO.getId());
            SysVideoPO sysVideoPO=new SysVideoPO();
            sysVideoPO.setVideoState(2);
            sysVideoPO.setDramaId("");
            sysVideoDao.updateByExampleSelective(sysVideoPO,example);

            sysDramasPO.setDramaState(2);
            sysDramasPO.setDramasSchedule(1);
            sysDramasSchedulePO.setLogTitle("审核不通过，操作人："+sysUserPO.getUserName());
            sysDramasSchedulePO.setLogDesc("反馈意见："+vo.getExamineDesc());
            sysDramasSchedulePO.setLogAnnexName(vo.getExamineAnnexName());
            sysDramasSchedulePO.setLogAnnexUrl(vo.getExamineAnnexUrl());
            //同步信息表
            DramasExaminePO dramasExaminePO=dramasExamineDao.selectByPrimaryKey(vo.getId());
            dramasExaminePO.setFailedAnnexUrl(vo.getExamineAnnexUrl());
            dramasExaminePO.setFailedAnnexName(vo.getExamineAnnexName());
            dramasExaminePO.setFailedDesc(vo.getExamineDesc());
            dramasExamineDao.updateByPrimaryKeySelective(dramasExaminePO);
            new CompanyMessageThread(companyMessageDao, sysDramasPO.getCompanyId(),"剧目提审进度通知",
                    "剧目（剧名："+sysDramasPO.getDramaName()+"）审核不通过，详情前往【剧目管理】中进行查阅。"
                    ,"/drama",1,(String) StpUtil.getLoginId()).start();

        }
        opDataExamine(sysDramasPO, sysDramasSchedulePO);
        new SysLogThread(sysLogDao,Constants.SYS_LOG_MODULE[0],"审核剧目提审信息，剧目ID:"+sysDramasPO.getId(), (String) StpUtil.getLoginId()).start();
    }

    @Override
    public void goLiveExamine(SysDramasGoLineExamineVO vo) {
        SysDramasPO sysDramasPO=sysDramasDao.selectByPrimaryKey(vo.getId());
        if(sysDramasPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR);
        }
        if(sysDramasPO.getDramaState()!=5){
            throw new BusinessException(Type.FAIL.getCode(),"当前状态不能申请上线！");
        }
        sysDramasPO.preUpdate();
        SysUserPO sysUserPO=sysUserDao.selectByPrimaryKey(StpUtil.getLoginId());
        if(sysUserPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR);
        }
        SysDramasSchedulePO sysDramasSchedulePO=new SysDramasSchedulePO();
        sysDramasSchedulePO.setDramaId(sysDramasPO.getId());
        sysDramasSchedulePO.setLogType(5);
        if(vo.getExamineState()==1){
            sysDramasPO.setDramaState(7);
            sysDramasPO.setDramasSchedule(5);
            sysDramasSchedulePO.setLogState(4);
            sysDramasPO.setScheduleDateE(sysDramasPO.getUpdateDate());
            sysDramasSchedulePO.setLogTitle("确认上线，操作人："+sysUserPO.getUserName());
            new CompanyMessageThread(companyMessageDao, sysDramasPO.getCompanyId(),"剧目提审进度通知",
                    "剧目（剧名："+sysDramasPO.getDramaName()+"）上线审核通过，详情前往【剧目管理】中进行查阅。"
                    ,"/drama",1,(String) StpUtil.getLoginId()).start();
        }
        if(vo.getExamineState()==2){
            sysDramasPO.setDramaState(6);
            sysDramasPO.setDramasSchedule(3);
            sysDramasSchedulePO.setLogState(5);
            sysDramasSchedulePO.setLogTitle("上线驳回，操作人："+sysUserPO.getUserName());
            sysDramasSchedulePO.setLogDesc("驳回原因："+vo.getExamineDesc());
            //同步信息表
            DramasExaminePO dramasExaminePO=dramasExamineDao.selectByPrimaryKey(vo.getId());
            dramasExaminePO.setRejectDesc(vo.getExamineDesc());
            dramasExamineDao.updateByPrimaryKeySelective(dramasExaminePO);
            new CompanyMessageThread(companyMessageDao, sysDramasPO.getCompanyId(),"剧目提审进度通知",
                    "剧目（剧名："+sysDramasPO.getDramaName()+"）上线审核被驳回，详情前往【剧目管理】中进行查阅。"
                    ,"/drama",1,(String) StpUtil.getLoginId()).start();
        }
        opDataExamine(sysDramasPO, sysDramasSchedulePO);
        new SysLogThread(sysLogDao,Constants.SYS_LOG_MODULE[0],"审核剧目上线，剧目ID:"+sysDramasPO.getId(), (String) StpUtil.getLoginId()).start();
    }

    @Override
    public List<SysDramasExamineLogVO> getExamineList(SysDramasExamineLogSearchVO searchVO) {
        return sysDramasScheduleDao.getExamineList(searchVO);
    }

    @Override
    public void completeTranscoding(String id) {
        SysDramasPO sysDramasPO=sysDramasDao.selectByPrimaryKey(id);
        if(sysDramasPO==null){
            new BusinessException(Type.FAIL.getCode(),"剧目信息不存在！");
        }
        if(sysDramasPO.getDramaState()!=3){
            throw new BusinessException(Type.FAIL.getCode(),"当前状态不能完成转码！");
        }
        SysUserPO sysUserPO=sysUserDao.selectByPrimaryKey(StpUtil.getLoginId());
        if(sysUserPO==null){
            throw new BusinessException(Type.NOT_FOUND_ERROR);
        }
        Example example=new Example(SysVideoPO.class);
        example.and().andEqualTo("dramaId",id);
        Integer count=sysVideoDao.selectCountByExample(example);
        example =new Example(SysVideoPO.class);
        example.and().andEqualTo("dramaId",id).andEqualTo("videoTranscodingState",1);
        Integer completeCount=sysVideoDao.selectCountByExample(example);
        if(count!=completeCount){
            throw new BusinessException(Type.FAIL.getCode(),"存在未转码状态的视频，无法确认完成转码。");
        }
        sysDramasPO.setDramaState(4);
        sysDramasPO.preUpdate();
        sysDramasDao.updateByPrimaryKeySelective(sysDramasPO);

        SysDramasSchedulePO sysDramasSchedulePO=new SysDramasSchedulePO();
        sysDramasSchedulePO.setDramaId(sysDramasPO.getId());
        sysDramasSchedulePO.setLogState(3);
        sysDramasSchedulePO.setLogType(3);
        sysDramasSchedulePO.setLogTitle("确认剧目转码完成，操作人："+sysUserPO.getUserName());
        sysDramasSchedulePO.preInsert();
        sysDramasScheduleDao.insertSelective(sysDramasSchedulePO);

        new CompanyMessageThread(companyMessageDao, sysDramasPO.getCompanyId(),"剧目提审进度通知",
                "剧目（剧名："+sysDramasPO.getDramaName()+"）已完成转码，可发起上线申请，详情前往【剧目管理】中进行查阅。"
                ,"/drama",1,(String) StpUtil.getLoginId()).start();
    }

    @Override
    public void export_zip(IDEntity idEntity, HttpServletResponse response, HttpServletRequest request) {
        SysDramasPO sysDramasPO=sysDramasDao.selectByPrimaryKey(idEntity.getId());
        if(sysDramasPO==null){
            new BusinessException(Type.FAIL.getCode(),"剧目信息不存在！");
        }
        File infoFile= FileUtil.file(System.getProperty("user.dir") + "/zip/"+sysDramasPO.getId()+"/"+sysDramasPO.getDramaName()+"-剧目信息.xlsx");
        infoFile.mkdir();
        ExcelWriter writer = new ExcelWriter(infoFile);
        writer.renameSheet(0, "剧目信息");
        writer.setColumnWidth(0,30);
        writer.setColumnWidth(1,30);
            // 合并第0列
        SysCompanyPO sysCompanyPO=sysCompanyDao.selectByPrimaryKey(sysDramasPO.getCompanyId());
        writer.writeHeadRow(Arrays.asList( "标题", "信息"));
        writer.writeRow(Arrays.asList( "剧目ID", sysDramasPO.getId()));
        writer.writeRow(Arrays.asList( "剧目备案号", sysDramasPO.getDramaNo()));
        writer.writeRow(Arrays.asList( "剧目名称",sysDramasPO.getDramaName()));
        writer.writeRow(Arrays.asList( "剧目集数", sysDramasPO.getDramaNum()));
        writer.writeRow(Arrays.asList( "剧目制作方", sysCompanyPO.getCompanyName()));
        writer.close();
        //授权材料表URL
        File empowerFile= FileUtil.file(System.getProperty("user.dir") + "/zip/"+sysDramasPO.getId()+"/"+sysDramasPO.getDramaName()+"-播放授权材料"+sysDramasPO.getDramaEmpowerUrl().substring(sysDramasPO.getDramaEmpowerUrl().lastIndexOf(".")));
        HttpUtil.downloadFile(sysDramasPO.getDramaEmpowerUrl(), empowerFile);
        //备案信息表URL
        File filingsFile= FileUtil.file(System.getProperty("user.dir") + "/zip/"+sysDramasPO.getId()+"/"+sysDramasPO.getDramaName()+"-上线信息备案表"+sysDramasPO.getDramaFilingsUrl().substring(sysDramasPO.getDramaFilingsUrl().lastIndexOf(".")));
        HttpUtil.downloadFile(sysDramasPO.getDramaFilingsUrl(), filingsFile);
        File file= ZipUtil.zip(FileUtil.file(System.getProperty("user.dir") + "/zip/"+sysDramasPO.getId()+"/"+sysDramasPO.getDramaName()+"提审文件"+ DateUtil.format(new Date(),"yyyyMMddHHmmss") +".zip"), false,
                empowerFile,
                filingsFile,
                infoFile
        );
        try {
            //设置响应头
            response.setContentType("application/octet-stream");
            String encodedFilename = new String(file.getName().getBytes("UTF-8"), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + encodedFilename);
            ServletOutputStream out = response.getOutputStream();
            out.write(FileUtil.readBytes(file));
            out.flush();
            //关闭流
            out.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            FileUtil.del(System.getProperty("user.dir") + "/zip/"+sysDramasPO.getId()+"/");
        }

    }


    private void opDataExamine(SysDramasPO sysDramasPO, SysDramasSchedulePO sysDramasSchedulePO) {
        sysDramasSchedulePO.preInsert();
        int i = sysDramasScheduleDao.insertSelective(sysDramasSchedulePO);
        if (i == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
        int j = sysDramasDao.updateByPrimaryKeySelective(sysDramasPO);
        if (j == Constants.SQL_RETURN_SUCCESS) {
            throw new BusinessException(Type.FAIL);
        }
    }
}